package cn.stylefeng.guns.modular.system.service.Myservice;

import cn.stylefeng.guns.modular.system.entity.*;
import cn.stylefeng.guns.modular.system.mapper.DispatchOrderMapper;
import cn.stylefeng.guns.modular.system.mapper.PurchaseOrdersMapper;
import cn.stylefeng.guns.modular.system.model.params.PurchaseOrdersParam;
import cn.stylefeng.guns.modular.system.model.params.paramsDTO.CheckDTO;
import cn.stylefeng.guns.modular.system.model.params.paramsDTO.PurchaseDTO;
import cn.stylefeng.guns.modular.system.service.*;
import cn.stylefeng.guns.sys.core.StatusCode.DispatchOrderCode;
import cn.stylefeng.guns.sys.core.shiro.ShiroKit;
import cn.stylefeng.guns.sys.core.util.common.SystemConstant;
import cn.stylefeng.guns.sys.core.util.utility.Katrina_CJ_Utils;
import cn.stylefeng.guns.sys.core.util.utility.Order;
import cn.stylefeng.guns.sys.core.util.utility.StatusCode;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * 发货单线程池
 *
 * @Author : xiaofei
 * @Date: 2019/7/7
 */
@Service
public class DispathService extends ServiceImpl<DispatchOrderMapper, DispatchOrder> {

    private static final int threads = 10;
    private static final Logger logger = LoggerFactory.getLogger(DispathService.class);

    @Autowired
    private PurchaseOrdersService purchaseOrdersService;
    @Autowired
    private DispatchOrderService dispatchOrderService;
    @Autowired
    private DispatchOrderCheckService dispatchOrderCheckService;
    @Autowired
    private CheckDispatchService checkDispatchService;
    @Autowired
    private InventorySalesService inventorySalesService;
    @Autowired
    private InventoryOrderService inventoryOrderService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private ProductOrderService productOrderService;

    @Resource
    private TaskService taskService;
    @Resource
    private IdentityService identityService;
    @Resource
    private RuntimeService runtimeService;


    /**
     * 提交发货数量
     *
     * @return
     */
    public ResponseData submit(PurchaseOrdersParam purchaseOrdersParam) {
        //1.获取前台传来的数据
        List<PurchaseDTO> purchaseDTOS = JSON.parseArray(purchaseOrdersParam.getPurchaseDetail(), PurchaseDTO.class);
        StringBuilder dispatchIds = new StringBuilder();
        purchaseDTOS.stream().forEach(s -> {

            PurchaseOrders purchaseOrders = purchaseOrdersService.getById(s.getPurchaseId());
            if (ToolUtil.isNotEmpty(purchaseOrders)) {

                purchaseOrders.setHavaSend(purchaseOrders.getHavaSend().add(s.getDispatchNum()));
                purchaseOrders.setNotSend(purchaseOrders.getNotSend().subtract(s.getDispatchNum()));
                if(ToolUtil.isNotEmpty(s.getPrice())) {
                    purchaseOrders.setHavaSendPrice((purchaseOrders.getHavaSend()).multiply(s.getPrice()));
                }
                if (ToolUtil.isNotEmpty(s.getPrice())) {
                    purchaseOrders.setNotSendPrice((purchaseOrders.getNotSend()).multiply(s.getPrice()));
                }
                purchaseOrders.setDispatchNum(s.getDispatchNum().longValue());
                purchaseOrdersService.getBaseMapper().updateById(purchaseOrders);
            }
            dispatchIds.append(s.getPurchaseId() + ",");
        });

        //2.生成发货单
        DispatchOrder dispatchOrder = new DispatchOrder();
        dispatchOrder.setPurchaseOrdersId(dispatchIds.toString());
        dispatchOrder.setCheckCode(StatusCode.PENDING.getVal());
        dispatchOrder.setCreateTime(new Date());
        dispatchOrder.setDispatchCode(StatusCode.PENDINGSEND.getVal());

        //生成发货单编号
        DispatchOrder dispatchOrderLast = dispatchOrderService.getOne(new QueryWrapper<DispatchOrder>()
                .orderByDesc("id").last("limit 1"));
        if (ToolUtil.isNotEmpty(dispatchOrderLast)) {
            dispatchOrder.setOrderNum(Katrina_CJ_Utils.createOrderSerial(Order.SQ_, dispatchOrderLast.getId()));
        } else {
            dispatchOrder.setOrderNum(Katrina_CJ_Utils.createOrderSerial(Order.SQ_, (long) 1));
        }

        //开启流程
        identityService.setAuthenticatedUserId(ShiroKit.getUserNotNull().getId() + "");
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(SystemConstant.sendOrder);
        dispatchOrder.setProcessInstanceId(processInstance.getId());
        dispatchOrder.setDealerId(ShiroKit.getUser().getId());
        dispatchOrderService.save(dispatchOrder);

        //开启流程对应的任务
        Task vacationApply = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        //设置经销商提交任务的执行人
        taskService.setAssignee(vacationApply.getId(), ShiroKit.getUserNotNull().getId() + "");
        //完成经销商提交任务
        taskService.complete(vacationApply.getId());

        return ResponseData.success(200, "提交申请发货单成功", dispatchOrder);
    }

    /**
     * 审核提交
     *
     * @param checkDTO
     * @return
     */
    public void check(CheckDTO checkDTO) {

        DispatchOrderCheck dispatchOrderCheck = dispatchOrderCheckService.getById(checkDTO.getId());
        CheckDispatch checkDispatch = null;
        checkDispatch = new CheckDispatch();
        switch (dispatchOrderCheck.getStatus()) {
            case 0:
                judgeCondition(checkDTO, checkDispatch, dispatchOrderCheck, DispatchOrderCode.NODE2.getVal());
                break;
            case 1:
                judgeCondition(checkDTO, checkDispatch, dispatchOrderCheck, DispatchOrderCode.NODE3.getVal());
                break;
            case 2:
                judgeCondition(checkDTO, checkDispatch, dispatchOrderCheck, DispatchOrderCode.NODE4.getVal());
                break;
            case 3:
                judgeCondition(checkDTO, checkDispatch, dispatchOrderCheck, DispatchOrderCode.NODE5.getVal());
                break;
        }

        //插入审核记录表
        checkDispatch.setAdvice(checkDTO.getAdvice());
        checkDispatch.setAuditor(ShiroKit.getUserNotNull().getId());
        checkDispatch.setTime(new Date());
        checkDispatch.setIndetOrderId(checkDTO.getId());
        checkDispatchService.save(checkDispatch);

    }


    /**
     * 判断条件公用类
     *
     * @param checkDTO
     * @param checkDispatch
     * @param dispatchOrderCheck
     * @param node
     */
    public void judgeCondition(CheckDTO checkDTO, CheckDispatch checkDispatch, DispatchOrderCheck dispatchOrderCheck, Integer node) {

        checkDispatch.setNode(node);
        if (checkDTO.getCode() == StatusCode.SUCCESS.getVal()) {
            checkDispatch.setStatus(DispatchOrderCode.SUCESS.getVal());
            dispatchOrderCheck.setPass(DispatchOrderCode.SUCESS.getVal());
            dispatchOrderCheck.setStatus(node);
            dispatchOrderCheckService.getBaseMapper().updateById(dispatchOrderCheck);
        } else if (checkDTO.getCode() == StatusCode.FAIL.getVal()) {
            checkDispatch.setStatus(DispatchOrderCode.FAIL.getVal());
            dispatchOrderCheck.setPass(DispatchOrderCode.FAIL.getVal());
            dispatchOrderCheck.setStatus(DispatchOrderCode.FAIL.getVal());
            DispatchOrder dispatchOrder = dispatchOrderService.getById(checkDTO.getId());
            dispatchOrder.setCheckCode(DispatchOrderCode.FAIL.getVal());
            dispatchOrderService.getBaseMapper().updateById(dispatchOrder);
        }

    }

    /**
     * 退回节点
     *
     * @return
     */
    public ResponseData back(CheckDTO checkDTO) {
        //1判断角色
        if (ShiroKit.hasRole(DispatchOrderCode.NODE2.getMessage())) {
            //2只能退回到经销商
            returnNode0(checkDTO, DispatchOrderCode.NODE2.getVal());

        } else if (ShiroKit.hasRole(DispatchOrderCode.NODE3.getMessage())) {

            if (checkDTO.getCode() == DispatchOrderCode.NODE1.getVal()) {
                //3.退回到经销商节点
                returnNode0(checkDTO, DispatchOrderCode.NODE3.getVal());
            } else if (checkDTO.getCode() == DispatchOrderCode.NODE2.getVal()) {
                //4.退货到订货单节点
                returnNode1(checkDTO, DispatchOrderCode.PENDEING.getVal(), DispatchOrderCode.NODE3.getVal());
            }
        } else if (ShiroKit.hasRole(DispatchOrderCode.NODE4.getMessage())) {

            if (checkDTO.getCode() == DispatchOrderCode.NODE1.getVal()) {
                returnNode0(checkDTO, DispatchOrderCode.NODE4.getVal());
            } else if (checkDTO.getCode() == DispatchOrderCode.NODE2.getVal()) {
                returnNode1(checkDTO, DispatchOrderCode.PENDEING.getVal(), DispatchOrderCode.NODE4.getVal());
            } else if (checkDTO.getCode() == DispatchOrderCode.NODE3.getVal()) {
                returnNode1(checkDTO, DispatchOrderCode.NODE2.getVal(), DispatchOrderCode.NODE4.getVal());
            }
        } else if (ShiroKit.hasRole(DispatchOrderCode.NODE5.getMessage())) {

            if (checkDTO.getCode() == DispatchOrderCode.NODE1.getVal()) {
                returnNode0(checkDTO, DispatchOrderCode.NODE5.getVal());
            } else if (checkDTO.getCode() == DispatchOrderCode.NODE2.getVal()) {
                returnNode1(checkDTO, DispatchOrderCode.PENDEING.getVal(), DispatchOrderCode.NODE5.getVal());
            } else if (checkDTO.getCode() == DispatchOrderCode.NODE3.getVal()) {
                returnNode1(checkDTO, DispatchOrderCode.NODE2.getVal(), DispatchOrderCode.NODE5.getVal());
            } else if (checkDTO.getCode() == DispatchOrderCode.NODE4.getVal()) {
                returnNode1(checkDTO, DispatchOrderCode.NODE3.getVal(), DispatchOrderCode.NODE5.getVal());
            }
        }
        return ResponseData.success();
    }


    /**
     * 退回经销商封装方法
     *
     * @param checkDTO
     */
    @Nullable
    public void returnNode0(CheckDTO checkDTO, Integer node) {

        DispatchOrder dispatchOrder = dispatchOrderService.getById(dispatchOrderCheckService.getById(checkDTO.getId()).getDispatchOrderId());
        dispatchOrder.setCheckCode(DispatchOrderCode.BACK.getVal());
        dispatchOrderService.getBaseMapper().updateById(dispatchOrder);

        //插入发货单审核记录表中
        CheckDispatch checkDispatch = new CheckDispatch();
        checkDispatch.setIndetOrderId(dispatchOrder.getId());
        checkDispatch.setTime(new Date());
        checkDispatch.setAuditor(ShiroKit.getUserNotNull().getId());
        checkDispatch.setStatus(DispatchOrderCode.BACK.getVal());
        checkDispatch.setAdvice(checkDTO.getAdvice());
        checkDispatch.setNode(node);
        checkDispatchService.getBaseMapper().insert(checkDispatch);

        //删除记录，用户修改后等于重新下审核单
        dispatchOrderService.getBaseMapper().deleteById(checkDTO.getId());

    }

    /**
     * 退回订单到指定节点
     *
     * @param checkDTO
     */
    public void returnNode1(CheckDTO checkDTO, Integer status, Integer node) {

        //4.退回到 订单审核节点
        DispatchOrderCheck dispatchOrderCheck = dispatchOrderCheckService.getById(checkDTO.getId());
        dispatchOrderCheck.setStatus(status);
        dispatchOrderCheck.setAuditor(ShiroKit.getUserNotNull().getId());
        dispatchOrderCheck.setRemark(checkDTO.getAdvice());
        dispatchOrderCheck.setTime(new Date());
        dispatchOrderCheckService.getBaseMapper().updateById(dispatchOrderCheck);

        //审核记录
        CheckDispatch checkDispatch = new CheckDispatch();
        checkDispatch.setNode(node);
        checkDispatch.setAdvice(checkDTO.getAdvice());
        checkDispatch.setAuditor(ShiroKit.getUserNotNull().getId());
        checkDispatch.setStatus(DispatchOrderCode.BACK.getVal());
        checkDispatch.setTime(new Date());
        checkDispatch.setIndetOrderId(dispatchOrderCheckService.getById(checkDTO.getId()).getDispatchOrderId());
        checkDispatchService.getBaseMapper().insert(checkDispatch);
    }
}
